package Chanel;
use strict;
use warnings;
use utf8;

use Util;
require Login;

# command

#our $CMD_READ =   0b000001;
#our $CMD_WRITE =  0b000010;
#our $CMD_CREATE = 0b000100;
#our $CMD_REMOVE = 0b001000;
#our $CMD_JOIN =   0b010000;
#our $CMD_LEAVE =  0b100000;
#

our %chanels;

sub get_chanel {
	my ($id) = @_;
	return $chanels{$id};
}

sub list_chanel {
	my ($owner,$id) = @_;
	unless(my $c = $chanels{$id}){
		return "";
	}elsif($c->{list}{$owner}){
		if($c->{nolist}){
			return "no list for $id";
		}else{
			return "[".$c->{list_str}."]";
		}
	}else{
		return "";
	}
}
sub add_chanel {
	my ($owner,$id,%param) = @_;
	if($chanels{$id}){
		return 0;
	}else{
		$chanels{$id} = {
			nolist => $param{nolist},
			owner => $owner,
			messages => [],
			shift => 0,
			list => {},
			list_str => "",
			create => time(),
			last => time(),
			access => $param{access} || 0760,
			perm => $param{perm},
			title => $param{title} || $id,
		};
		return 1;
	}
}
sub del_chanel {
	my ($owner,$id) = @_;
	unless(my $c = $chanels{$id}){
		return 404;
	}elsif($c->{owner} eq $owner){
		my $ch = delete $chanels{$id};
		$ch->{lister}->stop if $ch->{lister};
		for my $u(@{$ch->{list}}){
			delete $Login::logins{$u}{chanels}{$id};
		}
		$ch->{messages} = undef;
		$ch->{list} = undef;
		return 0;
	}else{
		return 403;
	}
}
sub join_chanel{
	my($login,$id) = @_;
	if(my $c = $chanels{$id}){
		$c->{list}{$login} = 1;
		$Login::logins{$login}{chanels}{$id} = $c->{shift} + @{$c->{messages}};
		$c->{list_str} = join(", ", keys %{$c->{list}}) unless $c->{nolist};
		Command::put_message({type=>"notice", param1 => "join", param2 => $login, chanel => $id});
		return $c->{title};
	}else{
		return 0;
	}
}
sub rejoin_chanel{
	my($login,$newlogin,$id) = @_;
	if(my $c = $chanels{$id}){
		delete $c->{list}{$login};
		$c->{list}{$newlogin} = 1;
		$c->{list_str} = join(", ", keys %{$c->{list}}) unless $c->{nolist};
		Command::put_message({type=>"notice", param1 => "rejoin", param2 => $login, param3 => $newlogin, chanel => $id});
		return $c->{title};
	}else{
		return 0;
	}
}
sub leave_chanel{
	my($login,$id,$new_sid) = @_;
	if(my $c = $chanels{$id}){
		delete $c->{list}{$login};
		delete $Login::logins{$login}{chanels}{$id};
		unless($c->{nolist}){
			unless($c->{list_str} = join(", ", keys %{$c->{list}})){
				unless($c->{perm}){
					$c->{messages} = undef;
					$c->{list} = undef;
					delete $chanels{$id};
				}
			}elsif(!$new_sid){
				Command::put_message({type=>"notice",param1 => "leave", param2 => $login, chanel => $id});
			}
		}
		return 1;
	}else{
		return 0;
	}
}
sub can_join {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		return 1;
	}else{
		return 0;
	}
}
sub can_leave {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		if($c->{list}{$login}){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}
sub can_create {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		return 0;
	}else{
		return 1;
	}
}
sub can_remove {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		if($c->{owner} eq $login){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}
sub can_message {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		if($c->{list}{$login}){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}
sub can_raw {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		if($c->{list}{$login}){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}
sub can_list {
	my ($chanel,$login) = @_;
	unless($chanel){
		return 0;
	}elsif(my $c = $chanels{$chanel}){
		if($c->{list}{$login}){
			return 1;
		}else{
			return 0;
		}
	}else{
		return 0;
	}
}

1;
